package com.spzx.cart.service.impl;

import com.spzx.cart.api.RemoteCartService;
import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;

    //自定义构建的redis主键，用于存储用户的购物车信息
    private String getCartKey(Long userId) {
        return "user:cart:" + userId;
    }

    //添加商品到购物车
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取当前用户的id
        Long userId = SecurityContextHolder.getUserId();
        //构建用户的购物车hash结构 大Key userId  小Key skuId  value cartInfo
        String cartKey = getCartKey(userId);
        //创建Hash结构绑定操作对象
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);

        //判断用户购物车中是否包含该商品 单件物品数量上限99 不包含
        String hashKey = skuId.toString();
        Integer threshold = 99;
        //如果包含 则数量相加     不包含 则添加新的商品信息    商品信息从商品微服务中获取   数量为用户传入的数量   选中状态为true    最后保存到redis中 \
        if (hashOps.hasKey(hashKey)) {
            //不是第一次添加该商品到购物车
            CartInfo cartInfo = hashOps.get(hashKey);
            int totalCount = cartInfo.getSkuNum() + skuNum;// 计算总数量
            cartInfo.setSkuNum(totalCount > threshold ? totalCount : threshold);
            hashOps.put(hashKey, cartInfo);
        } else {
//首次添加商品到购物车
            //判断购物车商品种类总数>50 则不添加  否则添加
            Long count = hashOps.size();
            if (++count > 50) {
                throw new ServiceException("商品的种类数量超过上限了！");
            }
            //购物车没有该商品  则添加该商品信息到购物车中，存入缓存
            CartInfo cartInfo = new CartInfo();

            cartInfo.setUserId(userId);  //大key
            cartInfo.setSkuNum(skuNum > threshold ? threshold : skuNum); // 数量
            cartInfo.setUpdateTime(new Date());
            cartInfo.setCreateTime(new Date());

            //远程调用商品服务获取商品sku信息
            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);

            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setThumbImg(productSku.getThumbImg());

            //远程调用商品服务获取商品的实时价格
            R<SkuPrice> skuPriceResult = remoteProductService.getSkuPrice(skuId, SecurityConstants.INNER);
            if (R.FAIL == skuPriceResult.getCode()) {
                throw new ServiceException(skuPriceResult.getMsg());
            }
            SkuPrice skuPrice = skuPriceResult.getData();
            cartInfo.setCartPrice(skuPrice.getSalePrice());
            cartInfo.setSkuPrice(skuPrice.getSalePrice());

            hashOps.put(hashKey, cartInfo);

        }

    }

    //获取购物车列表信息
    @Override
    public List<CartInfo> getCartList() {
        //从线程种获取用户id
        Long userId = SecurityContextHolder.getUserId();
        //构建用户的购物车hash结构 大Key userId  小Key skuId  value cartInfo
        String cartKey = this.getCartKey(userId);
        //获取数据
        BoundHashOperations hashOperations = redisTemplate.boundHashOps(cartKey);
        //获取购物车列表信息
        List<CartInfo> cartInfoList = hashOperations.values();
        //判断购物车列表是否为空3
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            //排序  按照创建时间倒序
            //infoList是排序后的购物车列表，它包含了用户购物车中的所有商品信息，按照创建时间倒序排列。
            List<CartInfo> infoList = cartInfoList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).toList();// 转换为列表并返回
            //获取skuId列表
            List<Long> skuIdList = infoList.stream().map(CartInfo::getSkuId).toList();
            //查询商品的价格
            R<List<SkuPrice>> SkuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
            //判断查询结果是否成功
            if (R.FAIL == SkuPriceListResult.getCode()) {
                throw new ServiceException(SkuPriceListResult.getMsg());
            }
            //查询结果转map集合
            Map<Long, BigDecimal> skuIdToPriceMap = SkuPriceListResult.getData().stream().collect(Collectors.toMap(SkuPrice::getSkuId,   //用skuPrice的skuId作为key
                    SkuPrice::getSalePrice));  // 用skuPrice的salePrice作为value
            //把商品服务获取的skuPrice列表，转成一个Map集合。可以通过skuId快速获取到对应的价格。

            infoList.forEach(item -> {
                //遍历购物车列表,为每个购物车项设置价格
                //设置实时价格
                item.setSkuPrice(skuIdToPriceMap.get(item.getSkuId()));// 先拿到skuId，再从map集合中获取对应的价格，根据skuId获取到对应的价格，然后设置到购物车项中。
            });
            return infoList;
        }
        return new ArrayList<>();
    }

    //删除购物车商品
    @Override
    public void deleteCart(Long skuId) {
        //获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        //构建主键
        String cartKey = this.getCartKey(userId);
        //获取缓存对象
        BoundHashOperations<String, String, CartInfo> hashOPerations = redisTemplate.boundHashOps(cartKey);
        //删除当前的商品
        hashOPerations.delete(skuId.toString());
    }

    //修改购物车商品选中状态
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        //构建主键
        String cartkey = this.getCartKey(userId);
        //获取缓存对象
        BoundHashOperations<String, String, CartInfo> hashOPerations = redisTemplate.boundHashOps(cartkey);
        //先获取用户选择的商品
        //在缓存对象里面获取用户选择的商品，根据skuId获取到对应的购物车项。
        if (hashOPerations.hasKey(skuId.toString())) { //找到这个次键了
            CartInfo cartInfoUpd = hashOPerations.get(skuId.toString()); //构建一个购物车对象，获取对应的这个skuId的对象
            //cartInfoUpd 写回缓存
            cartInfoUpd.setIsChecked(isChecked);//默认是选中的状态，看前端返回 的值决定这个结果
            //更新缓存
            hashOPerations.put(skuId.toString(), cartInfoUpd);//把这个购物车的对象写回缓存
        }
    }

    //修改购物车商品全部选中状态
    @Override
    public void allCheckCart(Integer isChecked) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKety = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOPerations = redisTemplate.boundHashOps(cartKety);
        //获取购物车列表信息
        List<CartInfo> cartInfoList = hashOPerations.values();
        cartInfoList.forEach(item -> {
            CartInfo cartInfoUpd = hashOPerations.get(item.getSkuId().toString());
            cartInfoUpd.setIsChecked(isChecked);
            //更新缓存
            hashOPerations.put(item.getSkuId().toString(), cartInfoUpd);
        });
    }

    //清空购物车
    @Override
    public void clearCart() {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = this.getCartKey(userId);
        redisTemplate.delete(cartKey);//直接删除了主键
    }

    //查询用户购物车列表中选中商品列表
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        List<CartInfo> cartInfoList = new ArrayList<>();//创建一个购物车列表
        String cartKey = this.getCartKey(userId);//构建主键
        List<CartInfo> cartCachInfoList = redisTemplate.opsForHash().values(cartKey);
        //获取缓存中的购物车列表
        if (!CollectionUtils.isEmpty(cartCachInfoList)) { //缓存中的购物车列表不为空
            for (CartInfo cartInfo : cartCachInfoList) {
                //获取选中的商品
                if (cartInfo.getIsChecked().intValue() == 1) {
                    cartInfoList.add(cartInfo);//添加到购物车列表中
                }
            }
        }
        return cartInfoList;
    }

    //更新购物车商品价格
    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartKey = this.getCartKey(userId);//设置主键
        BoundHashOperations hashOperations = redisTemplate.boundHashOps(cartKey);//获取缓存对象
        List<CartInfo> cartCachInfoList = hashOperations.values();//获取购物车列表信息
        if (!CollectionUtils.isEmpty(cartCachInfoList)) {
            for (CartInfo cartInfo : cartCachInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1) { //是被选中的商品
                    SkuPrice skuPrice = remoteProductService.getSkuPrice(cartInfo.getSkuId()//远程调用商品服务获取商品的实时价格
                            , SecurityConstants.INNER).getData();
                    cartInfo.setCartPrice(skuPrice.getSalePrice());//调整购物车的市场价格
                    cartInfo.setSkuPrice(skuPrice.getSalePrice());//调整购物车的实时价格
                    hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
                }
            }
        }

        return true;
    }

    //删除用户购物车列表中选中的商品列表
    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String cartKey = this.getCartKey(userId);
        BoundHashOperations hashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartCachInfoList = hashOperations.values();
        if (!CollectionUtils.isEmpty(cartCachInfoList)) {
            for (CartInfo cartInfo : cartCachInfoList) {
                if (cartInfo.getIsChecked().intValue() == 1) {
                    hashOperations.delete(cartInfo.getSkuId().toString());
                }
            }
        }
        return true;
    }
}